package dao;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import util.Conversion;
import dto.CandidateDTO;
import dto.EmployeeDTO;
import entities.Candidate;
import entities.Employee;

/**
 * Session Bean implementation class EmployeeDAO
 */
@Stateless
public class EmployeeDAO implements EmployeeDAORemote {

	@PersistenceContext
	EntityManager em;

	/**
	 * Default constructor.
	 */
	public EmployeeDAO() {
		// TODO Auto-generated constructor stub
	}

	Conversion conv;

	@Override
	public List<EmployeeDTO> getAllTesters() {
		List<EmployeeDTO> lista = new ArrayList<EmployeeDTO>();


		TypedQuery<Employee> query =  em.createQuery("SELECT e FROM Employee e WHERE e.rank= :eid", Employee.class);
		query.setParameter("eid", 2);



		List<Employee> result = query.getResultList();

		for (Employee e : result) {
			EmployeeDTO employees = new EmployeeDTO();
			employees.setId(e.getId());
			employees.setRank(e.getRank());
			employees.setUsername(e.getUsername());
			employees.setPassword(e.getPassword());
			employees.setName(e.getName());
			employees.setEmail(e.getEmail());
			lista.add(employees);
		}
		return lista;
	}
	
	@Override
	public List<EmployeeDTO> getAllAdmins() {
		List<EmployeeDTO> lista = new ArrayList<EmployeeDTO>();


		TypedQuery<Employee> query =  em.createQuery("SELECT e FROM Employee e WHERE e.rank= :eid", Employee.class);
		query.setParameter("eid", 1);



		List<Employee> result = query.getResultList();

		for (Employee e : result) {
			EmployeeDTO employees = new EmployeeDTO();
			employees.setId(e.getId());
			employees.setRank(e.getRank());
			employees.setUsername(e.getUsername());
			employees.setPassword(e.getPassword());
			employees.setName(e.getName());
			employees.setEmail(e.getEmail());
			lista.add(employees);
		}
		return lista;
	}

	@Override
	public EmployeeDTO findEmployeeByUsernameAndPassword(EmployeeDTO employeeDTO) {
		conv = new Conversion();
		TypedQuery<Employee> query = em
				.createQuery(
						"SELECT e FROM Employee e WHERE e.username = :usernameParam and e.password=:userpass",
						Employee.class);
		query.setParameter("usernameParam", employeeDTO.getUsername());
		query.setParameter("userpass", employeeDTO.getPassword());
		List<Employee> employee = query.getResultList();
		//System.out.println("FIND: " + employee.get(0).getId());
		EmployeeDTO result = null;
		if (employee != null && employee.size() > 0) {
			try {
				result = conv.fromEmployeeToEmployeeDTO(employee.get(0));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
		return result;
	}
	
	@Override
	public List<CandidateDTO> getAllCandidatesAllocatedForTester(EmployeeDTO eDTO) throws Exception{
		conv = new Conversion();
		TypedQuery<Candidate> query = em
				.createQuery(
						"SELECT distinct i.candidate FROM Interview i WHERE i.employee=:empl",
						Candidate.class);
		Employee e=em.find(Employee.class, eDTO.getId());
		query.setParameter("empl", e);
		List<Candidate> candidates = query.getResultList();
		List<CandidateDTO> cDTO= new ArrayList<CandidateDTO>();
		for(Candidate c:candidates){
			cDTO.add(conv.fromCandidateToCandidateDTO(c));
		}
		
		return cDTO;
	}
	
	@Override
	public void deleteEmployee(EmployeeDTO eDTO) throws Exception{
		Employee e=em.find(Employee.class, eDTO.getId());
		if(e!=null){
			em.remove(e);
		}else{
			throw new Exception("Employee could not been removed!");
		}
	}

	@Override
	public EmployeeDTO getEmployeeByEmailAndUsername(String email, String username) {
		conv = new Conversion();
		TypedQuery<Employee> query = em
				.createQuery(
						"SELECT e FROM Employee e WHERE e.username = :usernameParam OR e.email = :emailParam",
						Employee.class);
		query.setParameter("usernameParam", username);
		query.setParameter("emailParam", email);
		List<Employee> employee = query.getResultList();
		EmployeeDTO result = null;
		if (employee != null && employee.size() > 0) {
			try {
				result = conv.fromEmployeeToEmployeeDTO(employee.get(0));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
		return result;
	}

	@Override
	public void addEmployee(EmployeeDTO employee) {
		try {
			conv = new Conversion();
			//employee.setId();
			
			Employee emp = new Employee();
			emp.setEmail(employee.getEmail());
			//emp.setId(employee.getId());
			emp.setName(employee.getName());
			emp.setPassword(employee.getPassword());
			emp.setRank(employee.getRank());
			emp.setUsername(employee.getUsername());
			
			//Employee emp = conv.fromEmployeeDTOToEmployee(employee);
			emp.setPassword("1234");
			
				if(getEmployeeByEmailAndUsername(employee.getEmail(),employee.getUsername()) == null){
					em.persist(emp);
				}
				
			else
				throw new Exception(
						"Error adding new employee - employee allready exists");
		} catch (Exception e) {
			e.printStackTrace();
			try {
				throw new Exception("Error adding new employee!", e);
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
	
	@Override
	public void updateEmployee(EmployeeDTO oldEmployee,EmployeeDTO newEmployee) {
		// TODO Auto-generated method stub
		String query = "UPDATE Employees SET password = ? WHERE id = ?";		
		em.createNativeQuery(query).setParameter(1, newEmployee.getPassword())
				.setParameter(2,oldEmployee.getId()).executeUpdate();
	}
	
	@Override
	public List<EmployeeDTO> getAllTestersWithInterviews() throws Exception{
		conv = new Conversion();
		TypedQuery<Employee> query = em
				.createQuery(
						"SELECT e FROM Employee e WHERE e.rank=:rank",
						Employee.class);
		query.setParameter("rank", 2);
		List<Employee> employee = query.getResultList();
		List<EmployeeDTO> eDTO= new ArrayList<EmployeeDTO>();
		for(Employee e:employee){
			eDTO.add(conv.fromEmployeeToEmployeeDTOWithInterviews(e,e.getInterviews() ));
		}
	
		return eDTO;
	}
	
	@Override
	public List<CandidateDTO> getAllUnallocatedCandidates() throws Exception{
		conv = new Conversion();
		TypedQuery<Candidate> query = em
				.createQuery(
						"select c from Candidate c",
						Candidate.class);
		List<Candidate> candidates = query.getResultList();
		List<CandidateDTO> cDTO= new ArrayList<CandidateDTO>();
		for(Candidate c:candidates){
			if(c.getInterviews().size()==0)
			cDTO.add(conv.fromCandidateToCandidateDTO(c));
		}
	
		return cDTO;
	}
	
	@Override
	public List<CandidateDTO> getAllocatedCandidates() throws Exception{
		conv = new Conversion();
		TypedQuery<Candidate> query = em
				.createQuery(
						"select c from Candidate c",
						Candidate.class);
		List<Candidate> candidates = query.getResultList();
		List<CandidateDTO> cDTO= new ArrayList<CandidateDTO>();
		for(Candidate c:candidates){
			cDTO.add(conv.fromCandidateToCandidateDTO(c));
		}
	
		return cDTO;
	}
	
	@Override
	public EmployeeDTO getEmployeeById(int id){
		conv = new Conversion();
		Employee e=em.find(Employee.class, id);
		try {
			return conv.fromEmployeeToEmployeeDTO(e);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return null;
	}
	
	@Override
	public EmployeeDTO getEmployeeByEmail(String email){
		conv = new Conversion();
		TypedQuery<Employee> query = em
				.createQuery(
						"select e from Employee e where e.email like :param",
						Employee.class);
		query.setParameter("param", email);
		List<Employee> employees = query.getResultList();
		List<EmployeeDTO> eDTO= new ArrayList<EmployeeDTO>();
		for(Employee e:employees){
			try {
				eDTO.add(conv.fromEmployeeToEmployeeDTO(e));
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		if(eDTO.size()>0)
			return eDTO.get(0);
		return null;
	}
	
}
